package com.concurrent.data.thread.aop;

import com.concurrent.data.thread.common.Result;
import com.concurrent.data.thread.utils.FastJsonUtil;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 * @author 哲思小辉
 * @version 1.0.0
 * @ClassName RequestLogAspect.java
 * @Description 统一请求切面类
 * @Param
 * @createTime 2020年03月28日 17:08:00
 */
@Aspect
@Component
@Slf4j
public class RequestLogAspect {

    public final static ThreadLocal<Long> startTimes = new ThreadLocal<>();

    @Pointcut("execution(public * com.concurrent.data.thread.controller.*.*(..))")
    private void pointcut() {
    }


    @Around(value = "pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        val attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        val request = attributes.getRequest();
        val args = joinPoint.getArgs();
        val isLog = log.isInfoEnabled() || log.isDebugEnabled();
//        printBefore(request, args, isLog);
        // 用处理过的数据执行方法
        val proceed = joinPoint.proceed(args);
//        printAfter(request, isLog, proceed);
        return proceed;
    }

    /**
     * 前置日志打印
     */
    private void printBefore(HttpServletRequest request, Object[] args, boolean isLog) {
        if (isLog) {
            startTimes.set(System.currentTimeMillis());
            val str = new StringBuffer();
            str.append(" \n|--------------------------------------------------->");
            str.append(" \n| 请求IP：" + request.getRemoteAddr());
            str.append(" \n| 请求URL：" + request.getMethod() + " " + request.getRequestURL());
            str.append(" \n| 请求参数：" + Arrays.toString(args));
            str.append(" \n|---------------------------------------------------->");
            log.info(str.toString());
        }
    }

    /**
     * 后置日志打印
     */
    private void printAfter(HttpServletRequest request, boolean isLog, Object object) {
        if (isLog) {
            val endTime = System.currentTimeMillis();
            val startTime = startTimes.get();
            startTimes.remove();
            if (object instanceof Result) {
                log.info("\n|[{}]请求耗时：{} ms:\n---||返回数据: {}", request.getRequestURL(), endTime - startTime,
                        FastJsonUtil.toJson(object));
            } else {
                log.info("\n|[{}]请求耗时：{} ms", request.getRequestURL(), endTime - startTime);
            }
        }
    }


}
